home *** CD-ROM | disk | FTP | other *** search
- Path: EU.net!sun4nl!xs4all!usenet
- From: martijnl@xs4all.nl (Martijn Lievaart)
- Newsgroups: comp.lang.c++
- Subject: Re: Virtual Functions: How Implemented?
- Date: 2 Jan 1996 15:36:16 GMT
- Organization: XS4ALL, networking for the masses
- Message-ID: <4cbjdg$dra@news.xs4all.nl>
- References: <4c0d23$33n@vixen.cso.uiuc.edu>
- NNTP-Posting-Host: mas01-15.dial.xs4all.nl
- X-Newsreader: WinVN 0.99.6
-
- In article <4c0d23$33n@vixen.cso.uiuc.edu>, sjmccaug@prairienet.orgĂ® says...
- >
- >
- > // suppose base-class 'bc' was defined earlier ...
- >
- > dc1 dco1; // dc1 is the first class derived from 'bc'
- > dc2 dco2; // dc2 is the second derived class
- > int x,y;
- >
- > . . . . .
- >
- > bc *bc_ptr = x < y ? &dc01 : &dc02; // x,y defined at runtime
- >
- > base-class 'bc' contains a virtual function: value(), which gets re-defined
- > in bothe 'dc1' and 'dc2'. If the type argument to a cast operator could be
- > determined at runtime, one could say:
- >
- > ( (bc_ptr->_type_) * )bc_ptr->value();
- >
- > where '_type_' is an internal field of each instantiated object that carries
- > its class for runtime determination and is itself initialized upon
- instantia-
- > tion.
- > Since the type argument to a cast is NOT runtime-computable, how is the
- virtual
- > function scheme implemented?
-
- It's done using so-called vtables. It works like this. A (hidden) data member
- is added to bc and all it's derived classes, the vtable pointer. This points
- to a table that contains the adresses of the virtual functions. The statement
- bc_ptr->value() would get the adress of the function from the table. If bc_ptr
- points to a dc1 then the vtable from that object is used wich ofcourse points
- to the vtable of dc1 and dc1::value() will be called.
-
- Confused? picture this.
- In c you could do the same by adding a function ptr to your struct. Whenever
- you construct a new object, you would fill in this ptr with the appropriate
- adress (i.e. bc_value, dc1_value).
- When you want to compute value you would do something like:
- (*bc_ptr->pvalue)()
- and the right function would be called. It is what you try to create above.
- There is only one thing wrong with this technique, when you have more than one
- 'virtual' function ptr, these are duplicated in every object. Therefore c++
- constructs 1 table per class (the vtable for that class) and adds a ptr to
- that table, thereby taking only space for one pointer instead of several.
-
- Some observations can be made about this, sometimes you have to be aware of
- these, though they are mostly moot.
- - The size of any class with virtual functions is bigger than of the same
- class without, because the vtable ptr is added to the class.
- - You cannot rely on the ordering of the members as the vtable ptr is inserted
- (usualy at the start of the object). (you can not anyhow, except when you make
- all members public i.e. a c-struct)
- - Virtual functions take two ptr dereferences and therefore are slower than
- nonvirtual functions. But it is an efficient way to do what you want if you
- need the functionality. If you really, really, really, really, really, really,
- really need the utmost speed (hey, liven up, this is the age of the Pentium!),
- try to do it the 'c-ish way' and see if that helps. Most of the time redisign
- of algorithms works better though.
-
- Wow, long story, hope this helps.
-
-
-